
package com.erics.base;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * Application context holder.
 */
public class ApplicationContextHolder implements ApplicationContextAware {

    // 用于持有应用上下文的静态变量，便于全局访问Spring容器中的Bean
    private static ApplicationContext CONTEXT;

    /**
     * 实现ApplicationContextAware接口的方法。
     * 当Spring容器初始化时，会自动调用此方法将ApplicationContext注入到静态变量CONTEXT中。
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHolder.CONTEXT = applicationContext;
    }   

    /**
     * 根据类型获取Spring容器中的Bean。
     * 
     * @param clazz Bean的类型
     * @return 对应类型的Bean实例
     */
    public static <T> T getBean(Class<T> clazz) {
        return CONTEXT.getBean(clazz);
    }

    /**
     * 根据名称获取Spring容器中的Bean。
     * 
     * @param name Bean的名称
     * @return 名称为name的Bean实例
     */
    public static Object getBean(String name) {
        return CONTEXT.getBean(name);
    }

    /**
     * 根据名称和类型获取Spring容器中的Bean。
     * 
     * @param name Bean的名称
     * @param clazz Bean的类型
     * @return 名称和类型匹配的Bean实例
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return CONTEXT.getBean(name, clazz);
    }

    /**
     * 获取Spring容器中指定类型的所有Bean。
     * 
     * @param clazz Bean的类型
     * @return 类型为clazz的所有Bean，以Map形式返回（键为Bean名称，值为Bean实例）
     */
    public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
        return CONTEXT.getBeansOfType(clazz);
    }

    /**
     * 查找指定Bean上是否存在特定类型的注解。
     * 
     * @param beanName 要查找的Bean名称
     * @param annotationType 注解的类型
     * @return 如果存在该注解，则返回对应的注解对象；否则返回null
     */
    public static <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) {
        return CONTEXT.findAnnotationOnBean(beanName, annotationType);
    }

    /**
     * 获取当前应用的ApplicationContext实例。
     * 
     * @return Spring应用上下文对象
     */
    public static ApplicationContext getInstance() {
        return CONTEXT;
    }
}
